package com.dir.net.controller;

import com.alibaba.fastjson.JSON;
import com.dir.net.pojo.PacketInfo;
import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;
import jpcap.packet.Packet;
import lombok.Data;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

//抓包的线程
@Data
@Component
public class PacketCapture implements Runnable {
    @Resource
    MongoTemplate mongoTemplate;

    //网卡设备
    NetworkInterface device;
    //抓到的包
    ArrayList<Packet> packets = new ArrayList<>();
    //过滤信息
    Map<String, String> filter = new HashMap<>();
    //是否工作
    boolean work;
    //日期
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void run() {
        JpcapCaptor jpcapCaptor = null;
        try {
            jpcapCaptor = JpcapCaptor.openDevice(device, 65535, true, 2000);
            while (true) {
                Thread.sleep(100);
                Packet packet = jpcapCaptor.getPacket();
                if (packet != null && check(packet)) {
                    packets.add(packet);
                    getDetails(packet);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (jpcapCaptor != null) {
                jpcapCaptor.close();
            }
        }
    }

    public ArrayList<Map<String, String>> getPacketsDetails() {
        List<PacketInfo> packetInfos = mongoTemplate.findAll(PacketInfo.class);
        ArrayList<Map<String, String>> results = new ArrayList<>();
        for (PacketInfo packetInfo : packetInfos) {
            results.add(JSON.parseObject(packetInfo.getInfo(), Map.class));
        }
        return results;
    }


    void getDetails(Packet packet) {
        Map<String, String> detail = new PacketAnalyze(packet).analyze();
        detail.put("time", format.format(new Date()));
        mongoTemplate.insert(PacketInfo.builder().info(JSON.toJSONString(detail)).build());
    }

    public void clearList() {
        packets.clear();
        mongoTemplate.remove(new Query(), "packetInfo");
    }

    boolean check(Packet packet) {
        Map<String, String> detail = new PacketAnalyze(packet).analyze();
        for (Map.Entry<String, String> entry : filter.entrySet()) {
            String k = entry.getKey();
            String v = entry.getValue().trim();
            if (k.equals("keyword") && !v.isEmpty()) {
                boolean ff = false;
                for (Map.Entry<String, String> e : detail.entrySet()) {
                    if (e.getKey().contains(v) || e.getValue().contains(v)) {
                        ff = true;
                        break;
                    }
                }
                if (!ff) return false;
            } else if (k.equals("源IP")) {
                if (!detail.containsKey("源IP") || !detail.get("源IP").contains(v)) return false;
            } else if (k.equals("目的IP")) {
                if (!detail.containsKey("目的IP") || !detail.get("目的IP").contains(v)) return false;
            } else if (k.equals("协议类型")) {
                Set<String> protocols = new HashSet<String>(Arrays.asList("TCP", "IP", "UDP", "ICMP", "ARP"));
                if (v.equals("其他") && protocols.contains(detail.get(k))) {
                    return false;
                }
                if (!v.equals("全部") && !v.equals(detail.get(k))) return false;
            }
        }
        return true;
    }
}
